home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / XML Utilities / Professional Programmer XSL IDE / Xselerator25.msi / Data.Cab / F25558_SimpleBar.xsl < prev    next >
Encoding:
Extensible Markup Language  |  2002-03-03  |  8.0 KB  |  163 lines

  1. <?xml version="1.0"?>
  2. <xsl:stylesheet version="1.0" 
  3.   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  4.   xmlns:svg="http://www.w3.org/2000/svg">
  5. <xsl:output method="xml" indent="yes"/>
  6. <!-- global variable for bar width -->
  7. <xsl:variable name="bar_width" select="number(80)"/>
  8. <!-- spacing between bars -->
  9. <xsl:variable name="bar_spacing" select="number(10)"/>
  10. <!-- graph height scaling -->
  11. <xsl:variable name="graph_height" select="number(500)"/>
  12. <xsl:variable name="left_margin" select="number(100)"/>
  13.  
  14. <xsl:template match="/">
  15.   <!-- body root of svg -->
  16.   <svg:svg id="body" viewBox="0 0 -100 {$graph_height + 100}">
  17.     <!-- script for showing/hiding actual value hints on bars -->
  18.       <script type="text/ecmascript"><![CDATA[
  19.       function DoOnOver(evt,HintId){
  20.         // get document...
  21.         var target = evt.getTarget();
  22.         var doc = target.getOwnerDocument();
  23.         // get the hint graphic...
  24.         var Hint = doc.getElementById(HintId);
  25.         // make hint graphic visible...
  26.         Hint.setAttribute('style', 'visibility:visible');
  27.       }
  28.       function DoOnOut(evt,HintId){
  29.         // get document...
  30.         var target = evt.getTarget();
  31.         var doc = target.getOwnerDocument();
  32.         // get the hint graphic...
  33.         var Hint = doc.getElementById(HintId);
  34.         // make hint graphic visible...
  35.         Hint.setAttribute('style', 'visibility:hidden');
  36.       }
  37.       ]]></script>
  38.     <!-- graphic title -->
  39.     <svg:title>Weekly Sales Values</svg:title>
  40.     <!-- main graphic -->
  41.     <svg:g id="barChart" transform="translate(10, 10)" fill-rule="nonzero" clip-rule="nonzero" stroke="none" class="legend"
  42.       stroke-width="1" stroke-linecap="square" stroke-miterlimit="1" style="text-anchor:start" shape-rendering="crispEdges">
  43.       <!-- apply data -->
  44.       <xsl:apply-templates select="sales_summary"/>
  45.       <svg:text transform="matrix(2 0 0 2 {$left_margin} {$graph_height + 70})">Weekly Total Sales Values</svg:text>
  46.     </svg:g>
  47.   </svg:svg>
  48. </xsl:template>
  49.  
  50. <!-- main data template -->
  51. <xsl:template match="sales_summary">
  52.   <!-- calculate the number of weeks -->
  53.   <xsl:variable name="weeks_count" select="count(weekly_sales)"/>
  54.   <!-- calculate the maximum weekly sales value -->
  55.   <xsl:variable name="max_week_sales_value">
  56.     <xsl:for-each select="weekly_sales">
  57.       <xsl:sort select="sum(product_sales/@value)" data-type="number" order="descending"/>
  58.       <xsl:if test="position() = 1">
  59.         <xsl:value-of select="sum(product_sales/@value)"/>
  60.       </xsl:if>
  61.     </xsl:for-each>
  62.   </xsl:variable>
  63.   <!-- max graph height is max sales rounded to next 100 -->
  64.   <xsl:variable name="max_graph_height" select="floor(($max_week_sales_value + 99) div 100) * 100"/>
  65.   <!-- draw graph background -->
  66.   <xsl:call-template name="draw_graph">
  67.     <xsl:with-param name="max_graph_height" select="$max_graph_height"/>
  68.     <xsl:with-param name="bar_count" select="$weeks_count"/>
  69.   </xsl:call-template>
  70.   <!-- draw the graph bars themselves from data -->
  71.   <xsl:apply-templates select="weekly_sales">
  72.     <xsl:sort select="@week_no" data-type="number"/>
  73.     <xsl:with-param name="max_graph_height" select="$max_graph_height"/>
  74.   </xsl:apply-templates>
  75. </xsl:template>
  76.  
  77. <!-- draw graph background and vertical scale/legends -->
  78. <xsl:template name="draw_graph">
  79.   <xsl:param name="max_graph_height"/>
  80.   <xsl:param name="bar_count"/>
  81.   <xsl:variable name="actual_width" select="($bar_count * ($bar_width + $bar_spacing)) + $bar_spacing"/>
  82.   <svg:g id="GridAndLegend" style="stroke:none;" shape-rendering="crispEdges" stroke-width="1">
  83.     <!-- back face and surrounding lines -->
  84.     <svg:path fill="lightgray" stroke="black" d="M {$left_margin},{$graph_height + 20} h{$actual_width} v-{$graph_height} h-{$actual_width} v{$graph_height}"/>
  85.     <!-- draw zero mark and legend -->
  86.     <svg:path fill="none" stroke="black" d="M {$left_margin - 10},{$graph_height + 20} h10"/>
  87.     <svg:text text-anchor="end" baseline-shift="-3" transform="matrix(1 0 0 1 {$left_margin - 15} {$graph_height + 20})">0</svg:text>
  88.     <!-- draw vertical lines and legends -->
  89.     <xsl:call-template name="draw_graph_vertical_legends">
  90.       <xsl:with-param name="max" select="$max_graph_height"/>
  91.       <xsl:with-param name="legend_threshold" select="$max_graph_height div $graph_height"/>
  92.       <xsl:with-param name="actual_width" select="$actual_width"/>
  93.     </xsl:call-template>
  94.   </svg:g>
  95. </xsl:template>
  96.  
  97. <!-- recursive template to draw vertical lines and legends -->
  98. <xsl:template name="draw_graph_vertical_legends">
  99.   <xsl:param name="max"/>
  100.   <xsl:param name="legend_threshold"/>
  101.   <xsl:param name="actual_width"/>
  102.   <!-- params used only during recursion -->
  103.   <xsl:param name="start" select="number(100)"/>
  104.   <xsl:param name="step" select="number(100)"/>
  105.   <xsl:param name="prev_marked_start" select="number(0)"/>
  106.   <!-- calculate actual vertical 'pixel' position for this mark and previous drawn mark -->
  107.   <xsl:variable name="prev_vert_posn" select="($prev_marked_start div $max) * $graph_height"/>
  108.   <xsl:variable name="vert_posn" select="($start div $max) * $graph_height"/>
  109.   <!-- work out whether this line is too close to previous line -->
  110.   <xsl:variable name="new_marked_start">
  111.     <xsl:choose>
  112.       <xsl:when test="($vert_posn - $prev_vert_posn) >= $legend_threshold">
  113.         <xsl:value-of select="$start"/>
  114.       </xsl:when>
  115.       <xsl:otherwise>
  116.         <xsl:value-of select="$prev_marked_start"/>
  117.       </xsl:otherwise>
  118.     </xsl:choose>
  119.   </xsl:variable>
  120.   <!-- only draw line and legend when not too close -->
  121.   <xsl:if test="$new_marked_start = $start">
  122.     <svg:path fill="none" stroke="black" d="M {$left_margin - 10},{$graph_height + 20 - floor($vert_posn)} h{$actual_width + 10}"/>
  123.     <svg:text text-anchor="end" baseline-shift="-3" transform="matrix(1 0 0 1 {$left_margin - 15} {$graph_height + 20 - floor($vert_posn)})">
  124.       <xsl:value-of select="$start"/>
  125.     </svg:text>
  126.   </xsl:if>
  127.   <!-- if not yet reached max then recurse call to this template -->
  128.   <xsl:if test="$start < $max">
  129.     <xsl:call-template name="draw_graph_vertical_legends">
  130.       <xsl:with-param name="max" select="$max"/>
  131.       <xsl:with-param name="legend_threshold" select="$legend_threshold"/>
  132.       <xsl:with-param name="actual_width" select="$actual_width"/>
  133.       <xsl:with-param name="start" select="$start + $step"/>
  134.       <xsl:with-param name="step" select="$step"/>
  135.       <xsl:with-param name="prev_marked_start" select="$new_marked_start"/>
  136.     </xsl:call-template>
  137.   </xsl:if>
  138. </xsl:template>
  139.  
  140. <!-- applied template that draws bar for each week -->
  141. <xsl:template match="weekly_sales">
  142.   <xsl:param name="max_graph_height"/>
  143.   <!-- draw the bar for this week sales value -->
  144.   <xsl:variable name="sales_value" select="sum(product_sales/@value)"/>
  145.   <xsl:variable name="bar_height" select="floor(($sales_value div $max_graph_height) * $graph_height)"/>
  146.   <xsl:variable name="bar_left" select="((position() - 1) * ($bar_width + $bar_spacing)) + $bar_spacing"/>
  147.   <!-- draw the bar -->
  148.   <svg:path fill="lime" stroke="none" d="M {$bar_left + $left_margin},{$graph_height + 19} h{$bar_width} v-{$bar_height} h-{$bar_width} v{$bar_height}"
  149.    onmouseover="DoOnOver(evt,'Hint_{@week_no}')" onmouseout="DoOnOut(evt,'Hint_{@week_no}')"/>
  150.   <!-- draw the legend -->
  151.   <svg:text text-anchor="middle" transform="matrix(1.5 0 0 1.5 {$left_margin + $bar_left + ($bar_width div 2)} {$graph_height + 40})">
  152.     <xsl:text>Week </xsl:text>
  153.     <xsl:value-of select="@week_no"/>
  154.   </svg:text>
  155.   <!-- create the invisible hint info for the bar -->
  156.   <svg:g id="Hint_{@week_no}" style="visibility: hidden;">
  157.     <svg:path fill="none" stroke="red" d="M {$left_margin - 10},{$graph_height + 20 - $bar_height} h{$bar_left + 10}"/>
  158.     <svg:text transform="matrix(1 0 0 1 {$left_margin + $bar_left + 2} {($graph_height + 30) - $bar_height})">
  159.       <xsl:value-of select="format-number($sales_value,'#,##0')"/>
  160.     </svg:text>
  161.   </svg:g>
  162. </xsl:template>
  163. </xsl:stylesheet>